#'###########################################
#'                                          #
#'  ------------------------------------    #
#'  |     COIN     __                  |    #
#'  |            >(' )                 |    #
#'  |              )/                  |    #
#'  |             /  `----/            |    #
#'  |             \  ~=- /             |    #
#'  |   ~^~^~^~^~^~^~^~^~^~^~^~^~^~^   |    #
#'  ------------------------------------    #
#'                                          #
#'###########################################



#'#
#'# Charge les donnees Argos
#'#
load.data <- function (path=".", locsclasses = c(3, 2, 1, 0, "A", "B"), 
    argoscolumns=c("Platform.ID.", "Latitude", "Longitude", "Loc..quality", "Loc..date", "Sat.", "Jour", "Heure", "ID")) {
  if (file.info(path)$isdir) {
    data <- load.files(path, columns=argoscolumns)
    data <- do.call(rbind, data)
  } else {
    data <- read.table(path, header=TRUE)[, argoscolumns]
  }
  data.unique <- get.unique(data)
  setkey(data.unique, Loc..quality)
  setnames(data.unique, names(data.unique), ARGOS_COLUMN_NAMES[names(data.unique)])
  return(data.unique[locsclasses])
}


#'#
#'#  Charge tous les fichiers de donnees dans une liste
#'#
load.files <- function(path=".", tables=NULL, columns) {
    files <- list.files(path=path, pattern="*.txt", recursive=TRUE)
    gpsIndex <- grep(".*GPS[123]_.*", files)
    files <- file.path(path, files[-gpsIndex])
    tables <- vector("list", length(files))
    cpt <- 1
  
    for (i in files) {
        data <- read.table(i, header=TRUE)
        tables[[cpt]] <- data[, columns]
        names(tables)[cpt] <- paste(data$Jour[1], "_", 
            data$Platform.ID[1], sep="")
        cpt <- cpt+1
    }
  return (tables)
}


#'#
#'# Liste les repertoires uniquement dans un repertoire donne. Ne marche pas
#'# recursivement
#'#
list.dirs <- function (path=".", filelist=NULL, pattern=NULL, all.dirs=FALSE,
                      full.names=FALSE, ignore.case=FALSE) {
  
  if (is.null(filelist)) {
    filelist <- list.files(path, pattern, all.dirs,
                    full.names, recursive=FALSE, ignore.case)
  } 
  filelist <- paste(path, "/", filelist, sep="")
  filelist[file.info(filelist)$isdir]
}


#'#
#'# Verifie si le chemin possede des repertoires ou non.
#'# Peut prendre une liste de fichiers en parametre pour accelerer la recherche
#'#
has.dirs <- function (filelist=NULL, path=".", pattern=NULL, all.dirs=FALSE,
                      full.names=FALSE, ignore.case=FALSE) {
  if (is.null(filelist)) {
    return (length(list.dirs(path, pattern, all.dirs, full.names, ignore.case)) 
            != 0)
  }
  return (length(file.info(filelist)$isdir) != 0)
}


#'#
#'# Verifie si les chemins fournis possedent des fichiers
#'#
has.files <- function(path) {
  n <- length(path)
  result <- numeric(n)
  for (i in 1:n) {
    if (file.info(path[i])$isdir) {
      files <- file.path(path[i], list.files(path[i]))
      files <- files[!file.info(files)$isdir]
      result[i] <- (length(files) != 0)
    } else {
      result[i] <- FALSE
    }
  }
  return (result);
}


#'#
#'# Renvoie une data.table unique
#'# 
get.unique <- function(data) {
  return (data.table(unique(data)))
}


#'#
#'# Recupere les fichiers de donnees
#'# 
getDataFiles <- function(path, recursive=FALSE) {
  files <- file.path(path, list.files(path=path, include.dirs=FALSE, recursive=recursive))
  gpsIndex <- grep("GPS\\d_.*", files, perl=TRUE)
  gpsfiles <- files[gpsIndex]
  argosfiles <- files[-gpsIndex]
  return (list(gps=gpsfiles, argos=argosfiles))
}


#'#
#'# Recupere les donnees et renvoie une data.table
#'# 
getData <- function(files, columns, is.argos=FALSE) {
  if (length(files) == 1) {
		data <- data.table(readData(files, columns, is.argos))
  } else {
    data <- data.table(do.call(rbind,(lapply(files, readData, columns=columns, is.argos=is.argos))))
  }
	setnames(data, names(data), ARGOS_COLUMN_NAMES[names(data)])
	return(data)
} 


#'#
#'# Lit les donnees
#'# 
readData <- function(file, columns, is.argos) {
  if (is.argos) {
      res <- read.delim(file, stringsAsFactors=FALSE, sep="")
      return(unique(res[, columns[columns %in% colnames(res)]]))
  } else {
      res <- read.delim(file, stringsAsFactors=FALSE)
      return(res[, columns[columns %in% colnames(res)]])
  }
}


#'#
#'# Extract latitude and longitude from gps data
#'# 
extractGPSCoordinates <- function(gpsdata) {
  pos <- unlist(strsplit(gpsdata$position, " "))
  gpsdata$longitude <- as.numeric(pos[seq(3, length(pos), by = 4)])
  gpsdata$latitude <- as.numeric(pos[seq(4, length(pos), by = 4)])
  return(gpsdata)
}


#'#
#'# Project coordinates in NAD83, UTM 17
#'# 
projectArgosCoordinates <- function(argosdata) {
  xy_proj <- project(argosdata[, list(longitude, latitude)], c(proj = "utm",zone = 17,datum = "NAD83"),
      ellps.default = "GCS")
  argosdata[, argLong := xy_proj$x]
  argosdata[, argLat := xy_proj$y]
  return(argosdata)
}


#'#
#'# Verifie si un point est dans une ellipse
#'# 
isPointInEllipse <- function(x, y, x0, y0, r1, r2, theta) {
  t <- deg2rad(90 - theta)
  X <- (x - x0) * cos(t) + (y - y0) * sin(t); #' Translate and rotate coords.
  Y <- - (x - x0) * sin(t) + (y - y0) * cos(t); #' to align with ellipse
  points(X, Y)
  return ((X^2/r1^2 + Y^2/r2^2) <= 1)
}


#'#
#'# Trace une ellipse selon les parametres fournis
#'# 
ellipse <- function(hlaxa = 1, hlaxb = 1, theta = 0, xc = 0, yc = 0, 
    npoints = 100) {
  xp <- NULL
  yp <- NULL
  for(i in 0:npoints) {
    a <- (2 * pi * i)/npoints
    x <- hlaxa * cos(a)
    y <- hlaxb * sin(a)
    if (theta != 0) {
      alpha <- angle(x, y)
      rad <- sqrt(x^2 + y^2)
      x <- rad * cos(alpha + theta)
      y <- rad * sin(alpha + theta)
    }
    xp <- c(xp, x + xc)
    yp <- c(yp, y + yc)
  }
  lines(xp, yp, type = "l")
  invisible()
}


#'#
#'# Angle de l'ellipse
#'# 
angle <- function(x, y) {
  if(x > 0) {
    atan(y/x)
  } else {
    if(x < 0 & y != 0) {
      atan(y/x) + sign(y) * pi
    } else {
      if(x < 0 & y == 0) {
        pi
      } else {
        if(y != 0) {
          (sign(y) * pi)/2
        } else {
          NA
        }
      }
    }
  }
}


#'#
#'# Transforme des degres en radian
#'# 
deg2rad <- function(deg) {
  return (deg*pi/180)
}


#'#
#'# Remplace tous les na dans une data.table
#'# 
replaceall.na.dt <- function(DT, replace=0) {
	for (j in seq_len(ncol(DT))) {
		set(DT, which(is.na(DT[[j]])), j, replace)
	}
}


#'#
#'# Calcule la vitesse moyenne des positions GPS
#'# 
getAverageSpeed <- function(data) {
    gps <- data@gps
    n <- nrow(gps)
    tmp <- gps[, list(diffLat=latitude - c(gps[2:n, latitude], NA),
            diffLong=longitude - c(gps[2:n, longitude], NA),
            diffTime=difftime(time, gps[2:n, time], units="secs"))]
    tmp <- tmp[!is.na(diffLong)]
    tmp[, distance := sqrt(diffLong^2 + diffLat^2)]
    tmp[, vitesse := -(distance/as.numeric(diffTime) * 3600 / 1000)]
    setkey(tmp, vitesse)
    tmp <- tmp[vitesse > 0.3]
    return(tmp[, list(mean=mean(vitesse), sd=sd(vitesse), max=max(vitesse))])
}	